home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / mint104s.zoo / mint.src / tosfs.c < prev    next >
C/C++ Source or Header  |  1993-03-08  |  36KB  |  1,514 lines

  1. /*
  2. Copyright 1991,1992 Eric R. Smith.
  3. Copyright 1992 Atari Corporation.
  4. All rights reserved.
  5. */
  6.  
  7. /* a VERY simple tosfs.c 
  8.  * this one is extremely brain-damaged, but will serve OK for a
  9.  * skeleton in which to put a "real" tosfs.c
  10.  */
  11.  
  12. #include "mint.h"
  13.  
  14. /* if NEWWAY is defined, tosfs uses the new dup_cookie/release_cookie
  15.  * protocol to keep track of file cookies, instead of the old
  16.  * method of "timing"
  17.  */
  18. /* #define NEWWAY */
  19. #if 0
  20. #define COOKIE_DB(x) DEBUG(x)
  21. #else
  22. #define COOKIE_DB(x)
  23. #endif
  24.  
  25. /* if RO_FASCISM is defined, the read/write modes are enforced. This is
  26.  * a Good Thing, not fascist at all. Ask Allan Pratt why he chose
  27.  * that name sometime.
  28.  */
  29. #define RO_FASCISM
  30.  
  31. /* temporary code for debugging Falcon media change bug */
  32. #if 0
  33. #define MEDIA_DB(x) DEBUG(x)
  34. #else
  35. #define MEDIA_DB(x)
  36. #endif
  37.  
  38. /* search mask for anything OTHER THAN a volume label */
  39. #define FILEORDIR 0x37
  40.  
  41. char tmpbuf[PATH_MAX+1];
  42.  
  43. static long    ARGS_ON_STACK tos_root    P_((int drv, fcookie *fc));
  44. static long    ARGS_ON_STACK tos_lookup    P_((fcookie *dir, const char *name, fcookie *fc));
  45. static long    ARGS_ON_STACK tos_getxattr    P_((fcookie *fc, XATTR *xattr));
  46. static long    ARGS_ON_STACK tos_chattr    P_((fcookie *fc, int attrib));
  47. static long    ARGS_ON_STACK tos_chown    P_((fcookie *fc, int uid, int gid));
  48. static long    ARGS_ON_STACK tos_chmode    P_((fcookie *fc, unsigned mode));
  49. static long    ARGS_ON_STACK tos_mkdir    P_((fcookie *dir, const char *name, unsigned mode));
  50. static long    ARGS_ON_STACK tos_rmdir    P_((fcookie *dir, const char *name));
  51. static long    ARGS_ON_STACK tos_remove    P_((fcookie *dir, const char *name));
  52. static long    ARGS_ON_STACK tos_getname    P_((fcookie *root, fcookie *dir,
  53.                             char *pathname, int size));
  54. static long    ARGS_ON_STACK tos_rename    P_((fcookie *olddir, char *oldname,
  55.                     fcookie *newdir, const char *newname));
  56. static long    ARGS_ON_STACK tos_opendir    P_((DIR *dirh, int flags));
  57. static long    ARGS_ON_STACK tos_readdir    P_((DIR *dirh, char *nm, int nmlen, fcookie *));
  58. static long    ARGS_ON_STACK tos_rewinddir    P_((DIR *dirh));
  59. static long    ARGS_ON_STACK tos_closedir    P_((DIR *dirh));
  60. static long    ARGS_ON_STACK tos_pathconf    P_((fcookie *dir, int which));
  61. static long    ARGS_ON_STACK tos_dfree    P_((fcookie *dir, long *buf));
  62. static long    ARGS_ON_STACK tos_writelabel    P_((fcookie *dir, const char *name));
  63. static long    ARGS_ON_STACK tos_readlabel    P_((fcookie *dir, char *name, int namelen));
  64.  
  65. static long    ARGS_ON_STACK tos_creat    P_((fcookie *dir, const char *name, unsigned mode,
  66.                     int attrib, fcookie *fc));
  67. static DEVDRV *    ARGS_ON_STACK tos_getdev    P_((fcookie *fc, long *devsp));
  68. static long    ARGS_ON_STACK tos_open    P_((FILEPTR *f));
  69. static long    ARGS_ON_STACK tos_write    P_((FILEPTR *f, const char *buf, long bytes));
  70. static long    ARGS_ON_STACK tos_read    P_((FILEPTR *f, char *buf, long bytes));
  71. static long    ARGS_ON_STACK tos_lseek    P_((FILEPTR *f, long where, int whence));
  72. static long    ARGS_ON_STACK tos_ioctl    P_((FILEPTR *f, int mode, void *buf));
  73. static long    ARGS_ON_STACK tos_datime    P_((FILEPTR *f, short *time, int rwflag));
  74. static long    ARGS_ON_STACK tos_close    P_((FILEPTR *f, int pid));
  75. static long    ARGS_ON_STACK tos_dskchng    P_((int drv));
  76.  
  77. #ifdef NEWWAY
  78. static long    ARGS_ON_STACK tos_release P_((fcookie *fc));
  79. static long    ARGS_ON_STACK tos_dupcookie P_((fcookie *dst, fcookie *src));
  80. #endif
  81.  
  82. /* some routines from biosfs.c */
  83. extern long    ARGS_ON_STACK null_select    P_((FILEPTR *f, long p, int mode));
  84. extern void    ARGS_ON_STACK null_unselect    P_((FILEPTR *f, long p, int mode));
  85.  
  86. DEVDRV tos_device = {
  87.     tos_open, tos_write, tos_read, tos_lseek, tos_ioctl, tos_datime,
  88.     tos_close, null_select, null_unselect
  89. };
  90.  
  91. FILESYS tos_filesys = {
  92.     (FILESYS *)0,
  93.     FS_KNOPARSE | FS_NOXBIT | FS_LONGPATH,
  94.     tos_root,
  95.     tos_lookup, tos_creat, tos_getdev, tos_getxattr,
  96.     tos_chattr, tos_chown, tos_chmode,
  97.     tos_mkdir, tos_rmdir, tos_remove, tos_getname, tos_rename,
  98.     tos_opendir, tos_readdir, tos_rewinddir, tos_closedir,
  99.     tos_pathconf, tos_dfree, tos_writelabel, tos_readlabel,
  100.     nosymlink, noreadlink, nohardlink, nofscntl, tos_dskchng,
  101. #ifdef NEWWAY
  102.     tos_release, tos_dupcookie
  103. #else
  104.     0, 0
  105. #endif
  106. };
  107.  
  108. /* some utility functions and variables: see end of file */
  109. static DTABUF     *lastdta;    /* last DTA buffer we asked TOS about */
  110. static DTABUF    foo;
  111. static void do_setdta P_((DTABUF *dta));
  112. static int executable_extension P_((char *));
  113.  
  114. /* this array keeps track of which drives have been changed */
  115. /* a nonzero entry means that the corresponding drive has been changed,
  116.  * but GEMDOS doesn't know it yet
  117.  */
  118. static char drvchanged[NUM_DRIVES];
  119.  
  120. /* force TOS to see a media change */
  121. static void force_mediach P_((int drv));
  122. static long ARGS_ON_STACK Newgetbpb P_((int));
  123. static long ARGS_ON_STACK Newmediach P_((int));
  124. static long ARGS_ON_STACK Newrwabs P_((int, void *, int, int, int, long));
  125.  
  126. #ifdef NEWWAY
  127. #define NUM_INDICES 64
  128. #else
  129. #define NUM_INDICES 128
  130. #define MIN_AGE 8
  131. #endif
  132.  
  133. struct tindex {
  134.     char *name;        /* full path name */
  135.     FILEPTR *open;        /* fileptrs for this file; OR
  136.                  * count of number of open directories
  137.                  */
  138.     LOCK *locks;        /* locks on this file */
  139. /* file status */
  140.     long  size;
  141.     short time;
  142.     short date;
  143.     short attr;
  144.     short valid;        /* 1 if the above status is still valid */
  145. #ifdef NEWWAY
  146.     short links;        /* how many times index is in use */
  147. #else
  148.     short stamp;        /* age of this index, for garbage collection */
  149. #endif
  150. } gl_ti[NUM_INDICES];
  151.  
  152. /* temporary index for files found by readdir */
  153. static struct tindex tmpindex;
  154. static char tmpiname[PATH_MAX];
  155.  
  156. static struct tindex *tstrindex P_((char *s));
  157. static int tfullpath P_((char *result, struct tindex *base, const char *name));
  158. static struct tindex *garbage_collect P_((void));
  159.  
  160. #ifndef NEWWAY
  161. static short tclock;        /* #calls to tfullpath since last garbage
  162.                    collection */
  163. #endif
  164.  
  165. /* some extra flags for the attr field */
  166.  
  167. /*
  168.  * is a string the name of a file with executable extension?
  169.  */
  170. #define FA_EXEC 0x4000
  171. /*
  172.  * should the file be deleted when it is closed?
  173.  */
  174. #define FA_DELETE 0x2000
  175.  
  176. /*
  177.  * NOTE: call executable_extension only on a DTA name returned from
  178.  * Fsfirst(), not on an arbitrary path, for two reasons: (1) it
  179.  * expects only upper case, and (2) it looks only for the 1st extension,
  180.  * so a folder with a '.' in its name would confuse it.
  181.  */
  182.  
  183. static int
  184. executable_extension(s)
  185.     char *s;
  186. {
  187.     while (*s && *s != '.') s++;
  188.     if (!*s) return 0;
  189.     s++;
  190.     if (s[0] == 'T') {
  191.         return (s[1] == 'T' && s[2] == 'P') ||
  192.                (s[1] == 'O' && s[2] == 'S');
  193.     }
  194.     if (s[0] == 'P')
  195.         return s[1] == 'R' && s[2] == 'G';
  196.     if (s[0] == 'A')
  197.         return s[1] == 'P' && s[2] == 'P';
  198.     if (s[0] == 'G')
  199.         return s[1] == 'T' && s[2] == 'P';
  200.     return 0;
  201. }
  202.  
  203. /*
  204.  * Look in the table of tos indices to see if an index corresponding
  205.  * to this file name already exists. If so, mark it as being used
  206.  * and return it. If not, find an empty slot and make an index for
  207.  * this string. If no empty slots exist, garbage collect and
  208.  * try again.
  209.  *
  210.  * This routine is pretty dumb; we really should use a hash table
  211.  * of some sort
  212.  */
  213.  
  214. static struct tindex *tstrindex(s)
  215.     char *s;
  216. {
  217.     int i;
  218.     char *r;
  219.     struct tindex *t, *free = 0;
  220.  
  221.     assert(s != 0);
  222.     t = gl_ti;
  223.     for (i = 0; i < NUM_INDICES; i++, t++) {
  224.         if (t->name && !stricmp(t->name, s)) {
  225. #ifndef NEWWAY
  226.             t->stamp = tclock;    /* update use time */
  227. #endif
  228.             return t;
  229.         }
  230.         else if (!t->name && !free)
  231.             free = t;
  232.     }
  233.     if (!free) {
  234.         free = garbage_collect();
  235.     }
  236. #ifdef NEWWAY
  237.     if (!free) {
  238.         FORCE("tosfs: all slots in use!!");
  239.         FORCE("Links\tName");
  240.         t = gl_ti;
  241.         for (i = 0; i < NUM_INDICES; i++,t++) {
  242.             FORCE("%d\t%s", t->links, t->name);
  243.         }
  244.         FATAL("tosfs: unable to get a file name index");
  245.     }
  246. #else
  247.     if (!free) {
  248.         FATAL("tosfs: unable to get a file name index");
  249.     }
  250. #endif
  251.     r = kmalloc((long)strlen(s)+1);
  252.     if (!r) {
  253.         FATAL("tosfs: unable to allocate space for a file name");
  254.     }
  255.     strcpy(r, s);
  256.     free->name = r;
  257. #ifdef NEWWAY
  258.     free->links = 0;
  259. #else
  260.     free->stamp = tclock;
  261. #endif
  262.     free->open = 0;